﻿/*
 * 
 * Author: Martin Paulík
 * Designer: Michal Zbraněk
 * 
 */

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml;

namespace PB138___projekt
{
    /// <summary>
    /// Main form for working with xml file - delete, insert category, delete, insert media, import and export.
    /// </summary>
    public partial class Form1 : Form
    {
        XML xml = new XML();
        XmlNodeList mediaList;
        RichTextBox rich = new RichTextBox();
        Button but = new Button();
        ImportExport imp; 
        int current_index = 0; 

        /// <summary>
        /// Create components of form, insert categories to listBox and if categories is not empty, then selectedIndex is first in listBox.
        /// </summary>
        public Form1()
        {
            InitializeComponent();
            insertlistCategories();
            if(categoriesList.Items.Count > 0)
                categoriesList.SelectedIndex = 0; 
        }

        /// <summary>
        /// Insert list of categories to listBox. 
        /// </summary>
        private void insertlistCategories()
        {
            // get all categories from xml file
            List<string> categories = xml.getCategories();
            foreach (string category in categories)
            {
                categoriesList.Items.Add(category);
            }
        }
        /// <summary>
        /// Open form InsertMedia and refresh list of DVDs in listView.
        /// </summary>
        /// <param name="sender">Object</param>
        /// <param name="e">EventArgs</param>
        private void insertMediaToolStripMenuItem_Click(object sender, EventArgs e)
        {
            insertMedia dlg = new insertMedia();
            dlg.ShowDialog();
            refreshDVD();
        }

        /// <summary>
        /// Close this application. 
        /// </summary>
        /// <param name="sender">Object</param>
        /// <param name="e">EventArgs</param>
        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        /// <summary>
        /// Open form insertCategory and refresh list of categories in listBox. 
        /// </summary>
        /// <param name="sender">Object</param>
        /// <param name="e">EventArgs</param>
        private void insertCategoryToolStripMenuItem_Click(object sender, EventArgs e)
        {
            insertCategory dlg = new insertCategory();
            dlg.ShowDialog();
            refreshCategory(true);
        }

        /// <summary>
        /// Open form deleteCategory and refresh list of categories in listBox.
        /// </summary>
        /// <param name="sender">Object</param>
        /// <param name="e">EventArgs</param>
        private void deleteToolStripMenuItem_Click(object sender, EventArgs e)
        {
            deleteCategory dlg = new deleteCategory();
            dlg.ShowDialog();
            refreshCategory();
        }

        /// <summary>
        /// Open form programmers. 
        /// </summary>
        /// <param name="sender">Object</param>
        /// <param name="e">EventArgs</param>
        private void programmersToolStripMenuItem_Click(object sender, EventArgs e)
        {
            programmers dlg = new programmers();
            dlg.ShowDialog();
        }

        /// <summary>
        /// Refresh list of categories in listBox.
        /// </summary>
        /// <param name="value">If value is false, selectedIndex of listBox is 0, otherwise is current_index.</param>
        private void refreshCategory(bool value = false)
        {
            removeRichBut(null, null);
            xml = new XML();
            categoriesList.Items.Clear();
            insertlistCategories();
            if (categoriesList.Items.Count > 0)
            {
                if (value == false)
                    categoriesList.SelectedIndex = current_index = 0;
                else
                    categoriesList.SelectedIndex = current_index;
            }
        }

        /// <summary>
        /// Remove richTextBox, change columns by category and insert list of media by category
        /// </summary>
        /// <param name="sender">Object</param>
        /// <param name="e">EventArgs</param>
        private void categoriesList_SelectedIndexChanged(object sender, EventArgs e)
        {
            searchBox_Validated(new object(), new EventArgs());
            
            // Remove richTextbox with information about media 
            if (current_index != categoriesList.SelectedIndex)
            {
                removeRichBut(null, null);
            }
            current_index = categoriesList.SelectedIndex;
            filmListColumns();
            mediaList = xml.getListMedia((string)categoriesList.SelectedItem); 
            elaborationListMedia();
            
            

        }

        /// <summary>
        /// Remove richTextBox and button under. 
        /// </summary>
        /// <param name="sender">Object</param>
        /// <param name="e">EventArgs</param>
        private void removeRichBut(object sender, EventArgs e)
        {
            this.Controls.Remove(rich);
            rich = new RichTextBox();
            this.Controls.Remove(but);
            but = new Button();
            this.Size = new Size(727, 473);
            
        }

        /// <summary>
        /// Clear columns and insert basic columns - ID, name, author and item.
        /// </summary>
        private void filmListColumns() 
        {
            filmList.Columns.Clear();
            filmList.Columns.Add("ID");
            filmList.Columns.Add("name");
            filmList.Columns.Add("author");
            filmList.Columns.Add("item");
        }

        /// <summary>
        /// Clear listView and add rows with information about media
        /// </summary>
        private void elaborationListMedia()
        {
            filmList.Items.Clear();
            foreach (XmlNode medium in mediaList)
            {
                addRow(medium);
            }
        }

        /// <summary>
        /// Take information from med, insert to listViewItem item and add to listView. 
        /// </summary>
        /// <param name="med">XmlNode med is dvd with information</param>
        private void addRow(XmlNode med)
        {
            int i = 1;
            ListViewItem item = new ListViewItem();
            item.Text = med.Attributes["id"].Value;
            foreach (XmlNode child in med.ChildNodes)
            {
                if (filmList.Columns.Count <= i)
                {
                    filmList.Columns.Add("item");
                }
                while (child.Name != filmList.Columns[i].Text)
                {
                    i++;
                    item.SubItems.Add("");
                }
                item.SubItems.Add(child.Attributes[0].Value);
                i++;
            }
            filmList.Items.Add(item);

        }

        /// <summary>
        /// Override function for search media by film. 
        /// </summary>
        /// <param name="med">XmlNode medium which contains info</param>
        /// <param name="name">Name of category</param>
        /// <param name="searchFilm">Name of searching film</param>
        private void addRow(XmlNode med, string name, string searchFilm)
        {
            int i = 2;
            ListViewItem item = new ListViewItem();
            item.UseItemStyleForSubItems = false;
            item.Text = med.Attributes["id"].Value;
            item.SubItems.Add(name);
            foreach (XmlNode child in med.ChildNodes)
            {
                if (filmList.Columns.Count <= i)
                {
                    filmList.Columns.Add("item");
                }
                while (child.Name != filmList.Columns[i].Text)
                {
                    i++;
                    item.SubItems.Add("");
                }
                if (child.Attributes[0].Value == searchFilm && child.Name == "item")
                    item.SubItems.Add(new ListViewItem.ListViewSubItem (item, child.Attributes[0].Value, Color.Blue, Color.White, item.Font));
                else
                    item.SubItems.Add(child.Attributes[0].Value);
                
                i++;
            }
            filmList.Items.Add(item);
        }

        /// <summary>
        /// If user double-click on row in listView, form shows detailed information about media. 
        /// </summary>
        /// <param name="sender">Object</param>
        /// <param name="e">EventArgs</param>
        private void filmList_ItemActivate(object sender, EventArgs e)
        {
            removeRichBut(null, null);
            XmlNode medium = mediaList[filmList.SelectedItems[0].Index];
            rich = new RichTextBox();
            insertText(medium);
            rich.Location = new Point(705,26);
            rich.Size = new Size(300, 367);
            rich.Font = new Font("Arial",10, FontStyle.Bold);
            rich.BackColor = Color.White;
            rich.ReadOnly = true;
            this.Controls.Add(rich);
            
            but = new Button();
            but.Text = "<<";
            but.Font = new Font(but.Font, FontStyle.Bold);
            but.Location = new Point(830, 399);
            but.Click += new EventHandler(this.removeRichBut); 
            this.Controls.Add(but);
            this.Size = new Size(1027, 473);
        }
        /// <summary>
        /// Take information from medium and insert text to richTextBox. 
        /// </summary>
        /// <param name="medium">XmlNode medium which contains info (name, author, items)</param>
        private void insertText(XmlNode medium)
        {
            rich.Text = "Medium\n";
            rich.Text += "ID:\t" + medium.Attributes[0].Value + "\n";
            int j = 1;
            foreach (XmlNode child in medium.ChildNodes)
            {
                if (child.Name == "item")
                {
                    rich.Text += child.Name + " "+ j.ToString() + "\t"; 
                    int i = 0;
                    while (i < child.Attributes.Count)
                    {
                        rich.Text += child.Attributes[i].Name + ":\t" + child.Attributes[i].Value + "\n\t";
                        i++;

                    }
                    j++;
                }
                else
                {
                    rich.Text += child.Name + ":\t" + child.Attributes[0].Value;
                }
                rich.Text += "\n";
            }

        }

        /// <summary>
        /// Load from output.xml where are result of searching. Add columns ID, category, name, author and item.
        /// Add row to listView. 
        /// </summary>
        /// <param name="searchFilm">Name of searching film</param>
        public void searchingMedia(string searchFilm)
        {
            XmlDocument doc = new XmlDocument();
            doc.Load("output.xml");
            filmList.Clear();
            filmList.Columns.Add("ID");
            filmList.Columns.Add("category");
            filmList.Columns.Add("name");
            filmList.Columns.Add("author");
            filmList.Columns.Add("item");
            mediaList = doc.SelectNodes("media/dvd");
            filmList.Items.Clear();
            foreach (XmlNode medium in mediaList)
            {
                int index = Convert.ToInt32(medium.Attributes["category"].Value); 
                XmlNode category = xml.getCategory(index);
                addRow(medium,category.Attributes["name"].Value,searchFilm);
            }

        }

        /// <summary>
        /// Import by copy code. 
        /// </summary>
        /// <param name="sender">Object</param>
        /// <param name="e">EventArgs</param>
        private void byCopyCodeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            imp = new ImportExport(true, true);
            imp.ShowDialog();
            refreshCategory();
        }

        /// <summary>
        /// Import by application. 
        /// </summary>
        /// <param name="sender">Object</param>
        /// <param name="e">EventArgs</param>
        private void byApplicationToolStripMenuItem_Click(object sender, EventArgs e)
        {
            imp = new ImportExport(false, true);
            refreshCategory();

        }

        /// <summary>
        /// Export by copy code. 
        /// </summary>
        /// <param name="sender">Object</param>
        /// <param name="e">EventArgs</param>
        private void byCopyCodeToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            imp = new ImportExport(true);
            imp.ShowDialog();
        }

        /// <summary>
        /// Export by application. 
        /// </summary>
        /// <param name="sender">Object</param>
        /// <param name="e">EventArgs</param>
        private void byApplicationToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            imp = new ImportExport(false);
            imp.export(false);
        }

        /// <summary>
        /// Remove richTextBox with information about media and begin to search media by film. 
        /// </summary>
        /// <param name="sender">Object</param>
        /// <param name="e">EventArgs</param>
        private void button1_Click(object sender, EventArgs e)
        {
            removeRichBut(null,null);
            searchBox_Validating(new object(), new CancelEventArgs());
        }

        /// <summary>
        /// Check if textbox is valid. 
        /// </summary>
        /// <param name="sender">Object</param>
        /// <param name="e">EventArgs</param>
        /// If name was not found, show MessageBox. Otherwise show list of media in listView. 
        private void searchBox_Validating(object sender, CancelEventArgs e)
        {
            if (searchBox.Text.Length == 0)
            {
                searchBox.Select(0, searchBox.Text.Length);
                errorProvider1.SetError(searchBox, "The name is required !!");
            }
            else
            {
                if (xml.searchMedium(searchBox.Text) == true)
                {
                    searchingMedia(searchBox.Text);
                }
                else
                    MessageBox.Show("Name was not found","No found",System.Windows.Forms.MessageBoxButtons.OK,
                       System.Windows.Forms.MessageBoxIcon.Error);
            }
        }

        /// <summary>
        /// Stops showing of errorProvider.
        /// </summary>
        /// <param name="sender">Object</param>
        /// <param name="e">EventArgs</param>
        private void searchBox_Validated(object sender, EventArgs e)
        {
            errorProvider1.SetError(searchBox, "");
        }

        /// <summary>
        /// Delete marked row. 
        /// </summary>
        /// <param name="sender">Object</param>
        /// <param name="e">EventArgs</param>
        private void deleteMediaToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (filmList.SelectedItems.Count == 0)
            {
                MessageBox.Show("You didn't choose dvd to remove.", "ERROR", System.Windows.Forms.MessageBoxButtons.OK,
                       System.Windows.Forms.MessageBoxIcon.Error);
            }
            else
            {
                string idDVD = mediaList[filmList.SelectedItems[0].Index].Attributes["id"].Value;
                if (xml.deleteDVD(idDVD) == false)
                    MessageBox.Show("Error, delete have fail","ERROR", System.Windows.Forms.MessageBoxButtons.OK,
                       System.Windows.Forms.MessageBoxIcon.Error); 
                refreshDVD();
            }
        }

        /// <summary>
        /// Refresh list of DVD in listView. 
        /// </summary>
        private void refreshDVD()
        {
            xml = new XML();
            int index = current_index;
            if (current_index != 0)
                categoriesList.SelectedIndex = 0;
            else
                categoriesList.SelectedIndex = 1;
            categoriesList.SelectedIndex = current_index = index; 
        }

        /// <summary>
        /// For click key Enter in textBox for searching. 
        /// </summary>
        /// <param name="sender">Object</param>
        /// <param name="e">KeyEventArgs</param>
        private void searchBox_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyData == Keys.Enter)
                searchBox_Validating(new object(), new CancelEventArgs());
        }

    }
}
